﻿
using MCPlatform.MotionLib.Base;
using MCPlatform.MotionLib.Factory.LeadShine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MCPlatform.MotionLib.Factory.LeadShine
{
    public class LTIOModule : IIOModule
    {
        private ushort _cardNo;//卡号
        private ushort _portNo;
        //端口号保留参数，固定值为 0；所有输出口按顺序排列，每 32bit 为一个 port
        //口号，例如 portno = 0 表示 out0-out31，portno=1 表示 out32-out63，
        //以此类推；

        protected NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();//打印日志

        /// <summary>
        /// 读端口号全部输入点，返回集合
        /// </summary>
        public List<bool> IList
        {
            get
            {
                return IModule2IList();
            }
        }

        /// <summary>
        /// 读写端口号全部输出点，读的时候获取uint变量转换成集合，写的时候把集合转换成uint变量
        /// </summary>
        public List<bool> Qlist { get { return OModule2QList(); } set { QListInner2 = value; QList2OutPort(); } }

        List<bool> IListInner = new List<bool>();
        List<bool> QListInner1 = new List<bool>();
        List<bool> QListInner2 = new List<bool>();

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="cardNo">传入卡号</param>
        /// <param name="portNo">传入端口号</param>
        public LTIOModule(ushort cardNo, ushort portNo)
        {
            this._cardNo = cardNo;
            this._portNo = portNo;
        }

        /// <summary>
        /// 读全部输入口
        /// </summary>
        /// <returns>返回值的二进制代表各个输入口的电平</returns>
        /// <exception cref="Exception"></exception>
        public uint ReadInPort()
        {
            try
            {
                logger.Info("执行： LTDMC.dmc_read_inport");
                return LTDMC.dmc_read_inport(_cardNo, _portNo);
            }
            catch (Exception ex)
            {

                logger.Error("命令异常：" + "LTDMC.dmc_read_inport" + ex.Message);
                throw new Exception("命令：" + "LTDMC.dmc_read_inport" + ex.Message + "堆栈: " + ex.StackTrace);
            }
        }

        /// <summary>
        /// 读全部输出口状态
        /// </summary>
        /// <returns>返回值的二进制代表各个输出口的状态</returns>
        /// <exception cref="Exception"></exception>
        public uint ReadOutPort()
        {
            try
            {
                logger.Info("执行： LTDMC.dmc_read_outport");
                return LTDMC.dmc_read_outport(_cardNo, _portNo);
            }
            catch (Exception ex)
            {

                logger.Error("命令异常：" + "LTDMC.dmc_read_outport" + ex.Message);
                throw new Exception("命令：" + "LTDMC.dmc_read_outport" + ex.Message + "堆栈: " + ex.StackTrace);
            }
        }

        /// <summary>
        /// 写全部输出口
        /// </summary>
        /// <param name="portValue">端口值的二进制代表各个输出口应该如何写</param>
        /// <returns>错误代码</returns>
        /// <exception cref="Exception"></exception>
        public short WriteOutPort(uint portValue)
        {
            try
            {
                logger.Info("执行： LTDMC.dmc_write_outport");
                return LTDMC.dmc_write_outport(_cardNo, _portNo, portValue);
            }
            catch (Exception ex)
            {

                logger.Error("命令异常：" + "LTDMC.dmc_write_outport" + ex.Message);
                throw new Exception("命令：" + "LTDMC.dmc_write_outport" + ex.Message + "堆栈: " + ex.StackTrace);
            }
        }

        /// <summary>
        /// 读输入口时，此方法把uint变为集合
        /// </summary>
        /// <returns></returns>
        private List<bool> IModule2IList()
        {
            uint InportResult = ReadInPort();
            IListInner.Clear();
            for (int i = 0; i < 32; i++)
            {
                IListInner.Add((InportResult & (1 << i)) > 0);//uint 与每一位比较得出结果返回列表
            }
            return IListInner;
        }

        /// <summary>
        /// 把输出口状态变为集合
        /// </summary>
        /// <returns></returns>
        private List<bool> OModule2QList()
        {
            uint OutportResult = ReadOutPort();
            QListInner1.Clear();
            for (int i = 0; i < 32; i++)
            {
                QListInner1.Add((OutportResult & (1 << i)) > 0);//uint 与每一位比较得出结果返回列表
            }
            return QListInner1;
        }

        /// <summary>
        /// 把集合的输出口状态转成uint写入控制卡
        /// </summary>
        private void QList2OutPort()
        {
            int PortValve = 0;
            for (int i = 0; i < 32; i++)
            {
                if (QListInner2[i])
                {
                    PortValve = (PortValve | (1 << i));
                }

            }

            WriteOutPort((uint)PortValve);
        }



        /// <summary>
        /// 读单个输入点电平
        /// </summary>
        /// <param name="bitNo"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public short ReadInBit(ushort bitNo)
        {
            try
            {
                logger.Info("执行： LTDMC.dmc_read_inbit");
                return LTDMC.dmc_read_inbit(_cardNo, bitNo);
            }
            catch (Exception ex)
            {

                logger.Error("命令异常：" + "LTDMC.dmc_read_inbit" + ex.Message);
                throw new Exception("命令：" + "LTDMC.dmc_read_inbit" + ex.Message + "堆栈: " + ex.StackTrace);
            }
        }

        /// <summary>
        /// 读单个输出点电平
        /// </summary>
        /// <param name="bitNo"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public short ReadOutBit(ushort bitNo)
        {
            try
            {
                logger.Info("执行： LTDMC.dmc_read_inbit");
                return LTDMC.dmc_read_outbit(_cardNo, bitNo);
            }
            catch (Exception ex)
            {

                logger.Error("命令异常：" + "LTDMC.dmc_read_inbit" + ex.Message);
                throw new Exception("命令：" + "LTDMC.dmc_read_inbit" + ex.Message + "堆栈: " + ex.StackTrace);
            }
        }


        /// <summary>
        /// 写单个输出点电平
        /// </summary>
        /// <param name="bitNo"></param>
        /// <param name="onOrOff"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public short WriteOutBit(ushort bitNo, ushort onOrOff)
        {
            try
            {
                logger.Info("执行： LTDMC.dmc_write_outbit");
                return LTDMC.dmc_write_outbit(_cardNo, bitNo, onOrOff);
            }
            catch (Exception ex)
            {

                logger.Error("命令异常：" + "LTDMC.dmc_write_outbit" + ex.Message);
                throw new Exception("命令：" + "LTDMC.dmc_write_outbit" + ex.Message + "堆栈: " + ex.StackTrace);
            }
        }
    }
}
